﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections.Concurrent;
using BingoServerCommon.Common;
using BingoCommonConfig.Log4netConfig;

namespace BingoGameServerConsole
{
    public class WorkObject
    {
        public Package pack;
        public Session session;
        public Room room;
        public void Clear()
        {
            pack = null;
            session = null;
            room = null;
        }
    }
    public class Work
    {
        public int id;
        private List<Room> roomList = new List<Room>();
        private Dictionary<int, Room> roomDict = new Dictionary<int, Room>();
        private ConcurrentQueue<WorkObject> packQueue = new ConcurrentQueue<WorkObject>();//网络消息逻辑处理队列
        private Thread thread;
        private int maxRoomNum = 1;
        
        public static int curRoomID = 0;//当前房间索引ID  递增 递增  原子安全
        public Work(int _id)
        {
            id = _id;
            for (int i = 0; i < maxRoomNum; i++)
            {
                int rid = Interlocked.Increment(ref Work.curRoomID);
                Room room = new Room(rid);
                roomList.Add(room);
                roomDict.Add(rid, room);

                RoomManager.Instanse.AddRoom(rid, room);
            }
            thread = new Thread(new ThreadStart(WorkThreadFunc));
            thread.Start();
        }
        public Room AllocationRoom()
        {
            foreach (Room room in roomList)
            {
                if (room.IsEnter())
                {
                    return room;
                }
            }
            return null;
        }

        public void WorkThreadFunc()
        {
            long lastTime = 0;
            long checkDeleteTime = DateTime.Now.Ticks;
            long diff = 10000000 * 60 * (long)10;
            while (true)
            {
                if (packQueue.Count > 0)
                {
                    WorkObject obj = null;
                    packQueue.TryDequeue(out obj);
                    if (obj != null)
                    {
                        try
                        {
                            obj.pack.Excute(obj.room,obj.session);
                        }
                        catch(Exception e)
                        {
                            Console.WriteLine(e.Message);
                            LogHelper.WriteError(e);
                        }
                        obj.Clear();
                        obj = null;


                    }
                }
                try
                {
                    long curTicks = DateTime.Now.Ticks;
                    if (curTicks - lastTime >= 1000)
                    {
                        
                        foreach (Room room in roomList)
                        {
                            room.Update(curTicks);
                        }
                        lastTime = curTicks;
                    }
                }
                catch (Exception e)
                {
                    LogHelper.WriteError(e);
                }


                try
                {
                    long curTicks = DateTime.Now.Ticks;
                    
                    if (curTicks - checkDeleteTime >= diff)//10分钟检测一次 是否需要删除work
                    {
                        ///回收工作站
                        /*暂时不处理回收
                         foreach (Room room in roomList)
                        {
                            RoomManager.Instanse.DeleteRoom(room.id);
                        }
                        RoomManager.Instanse.DeleteWork(id);
                        checkDeleteTime = curTicks;
                        
                        break;//退出线程
                        */
                    }
                }
                catch (Exception e)
                {
                    LogHelper.WriteError(e);
                }
                Thread.Sleep(1);
            }
        }

        public void PushPackage(WorkObject obj)
        {
            packQueue.Enqueue(obj);
        }
    }
}
